package seek;

import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import sort.Sort;


public class Search {
    @Test
    public void test1() throws InterruptedException {
      int[] list=new int[]{1,2,3,4,5,6,6,6,7,7};
      System.out.println(interpolationSearch(list,1,0,list.length-1));





//        int[] list = getArray(100, 10);
//        System.out.println(Sort.getCurrentTime());
//        int result = binarySearch(list, 4, 0, list.length);
//        System.out.println(Sort.getCurrentTime());
//        System.out.println(result);









    }


    /**
     * 递归实现二分查找
     * @param list 欲查找的有序数组
     * @param value 欲查找的值
     * @param left 查找边界的左边
     * @param right 查找边界的右边
     * @return 首次查找的数字下标
     */
    private int binarySearch(int[] list,int value,int left,int right){
        int middle=(left+right)/2;
        if (list[middle]==value)
            return middle;
        if (left>right)
            return -1;
        if (list[middle]>value)
                //当前值大于value,向左查找
              return  binarySearch(list,value,left,middle-1);
        else {
                return binarySearch(list,value,middle+1,right);
        }
    }

    /**
     * 非递归实现二分查找
     * @param list 欲查找的有序数组
     * @param value 欲查找的值
     * @param left 查找边界的左边
     * @param right 查找边界的右边
     * @return 首次查找的数字下标
     */
    private int binarySearch1(int[] list,int value,int left,int right){
        int middle;
        while(left<right){
            middle=(left+right)/2;
            if (list[middle]==value)
                return middle;
            if (list[middle]<value){
                left=middle+1;
            }else if (list[middle]>value){
                right=middle-1;
            }
        }
        return -1;
    }

    /**
     * 插值查找算法与二分查找的区别在于middle的定义,插值查找算法对于middle的定义采用自适应算法进行优化,效率更高
     * @param list 欲查找的有序数组
     * @param value 欲查找的值
     * @param left 查找边界的左边
     * @param right 查找边界的右边
     * @return 首次查找的数字下标
     */
    private int interpolationSearch(int[] list,int value,int left,int right){
       int middle=left+(right-left)*(value-list[left])/(list[right]-list[left]);
        if (list[middle]==value)
            return middle;
        if (left>right)
            return -1;
        if (list[middle]>value)
            //当前值大于value,向左查找
            return  binarySearch(list,value,left,middle-1);
        else {
            return binarySearch(list,value,middle+1,right);
        }
    }







    /**
     * 该函数用于获取number个数子的数组,其中最大不超过bound
     * @param number
     * @param bound
     * @return 上述数组
     */
    private int[] getArray(int number,int bound){
        Random random = new Random();
        int[] list=new int[number];

        for (int i = 0; i < number; i++) {
            list[i]= random.nextInt(bound);
        }
        return list;
    }
}
